home *** CD-ROM | disk | FTP | other *** search
- /*
- * BC - Status (2002-03-08): ByteBuffer, BufferQueue
- *
- * None of these classes is considered part of the public API. Do NOT use it
- * in your apps. These are part of the implementation of libartsflow's
- * AudioSubSystem, and subject to change/disappearing due to optimization
- * work.
- */
-
- #ifndef _BUFFERQUEUE_H
- #define _BUFFERQUEUE_H
-
- #include "thread.h"
-
- #define _DEFAULT_CHUNK_SIZE 4096
- #define _MAX_CHUNKS 3
-
- namespace Arts
- {
-
- class ByteBuffer
- {
- unsigned char* content;
- int _size;
- int _maxSize;
- int rp;
-
- public:
- ByteBuffer() {
- _size = rp = 0;
- _maxSize = _DEFAULT_CHUNK_SIZE;
- content = new unsigned char[_DEFAULT_CHUNK_SIZE];
- }
- ByteBuffer(const void* s, int len) {
- _maxSize = _DEFAULT_CHUNK_SIZE;
- content = new unsigned char[_DEFAULT_CHUNK_SIZE];
- put(s, len);
- }
-
- ~ByteBuffer() { delete [] content; }
-
- void put(const void* s, int len) {
- if ((_size = len) != 0)
- memcpy(content, s, len);
- rp = 0;
- }
-
- void* get() { return content+rp; }
- void* reset() { _size = 0; rp = 0; return content; }
- int push(int len) { _size -= len; rp += len; return _size; }
- void set(int len) { _size = len; rp = 0; }
- int size() const { return _size; }
- int maxSize() const { return _maxSize; }
-
- void setMaxSize(int size) {
- delete [] content;
- content = new unsigned char[size];
- _maxSize = size;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
-
- class BufferQueue
- {
- private:
- ByteBuffer bufs[_MAX_CHUNKS];
- int rp;
- int wp;
- Arts::Semaphore* sema_produced;
- Arts::Semaphore* sema_consumed;
-
- void semaReinit() {
- delete sema_consumed;
- delete sema_produced;
- sema_consumed = new Arts::Semaphore(0, _MAX_CHUNKS);
- sema_produced = new Arts::Semaphore(0, 0);
- }
-
-
- public:
- BufferQueue() {
- rp = wp = 0;
- sema_consumed = new Arts::Semaphore(0, _MAX_CHUNKS);
- sema_produced = new Arts::Semaphore(0, 0);
- }
-
- ~BufferQueue() {
- delete sema_consumed;
- delete sema_produced;
- }
-
- void write(void* data, int len);
- ByteBuffer* waitConsumed();
- void produced();
-
- ByteBuffer* waitProduced();
- void consumed();
-
- bool isEmpty() const { return sema_produced->getValue() == 0; }
- int bufferedChunks() const { return sema_produced->getValue(); }
- int freeChunks() const { return sema_consumed->getValue(); }
- int maxChunks() const { return _MAX_CHUNKS; }
- int chunkSize() const { return bufs[0].maxSize(); }
- void clear() { rp = wp = 0; semaReinit(); }
- void setChunkSize(int size){
- for (int i=0; i < maxChunks(); i++)
- bufs[i].setMaxSize(size);
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
-
- inline void BufferQueue::write(void* data, int len)
- {
- sema_consumed->wait();
- bufs[wp].put(data, len);
- ++wp %= _MAX_CHUNKS;
- sema_produced->post();
- }
-
- inline ByteBuffer* BufferQueue::waitConsumed()
- {
- sema_consumed->wait();
- return &bufs[wp];
- }
-
- inline void BufferQueue::produced()
- {
- ++wp %= _MAX_CHUNKS;
- sema_produced->post();
- }
-
- inline ByteBuffer* BufferQueue::waitProduced()
- {
- sema_produced->wait();
- return &bufs[rp];
- }
-
- inline void BufferQueue::consumed()
- {
- ++rp %=_MAX_CHUNKS;
- sema_consumed->post();
- }
-
- }
-
- #endif
-